﻿package com.cilico.single.components;

import java.util.Vector;

import com.cilico.single.Mid;
import com.cilico.single.view.BaseView;
import com.cilico.single.view.Channel;
import com.cilico.single.view.DisplayPoi;

/**
 * 
 * @author lv.xiangan
 *
 */
public class PoiSelection {
	/** Stores a subset of poiVector_ to be shown on map. */
	private Vector<DisplayPoi> poiSelected_;

	/** Display index of current POI. */
	private int currentIndex_;

	/** Current channel; set during population from PoiRepository */
	public Channel channel_;

	/**
	 * Indicate when calculating the selected POI area, should current display view be included or not.
	 */
	private boolean includeCurDispView_;

	Mid mid_;
	public BaseView bv_;
	public PoiRepository poiRepo_;

	/**
	 * Basic constructor that does not pre-allocate storage for the vector.
	 */
	public PoiSelection(Mid mid) {
		poiSelected_ = new Vector<DisplayPoi>();
		currentIndex_ = -1;
		includeCurDispView_ = true;
		mid_ = mid;
	}

	/**
	 * Add one POI to the selection. We do NOT check for duplicates! If the max number of POIs reached, we kick out the
	 * previous last one.
	 * 
	 * @return: index added to the list
	 */
	public final DisplayPoi addPOI(POI p) {
		DisplayPoi pp = new DisplayPoi(p);
		poiSelected_.addElement(pp);
		return pp;
	}

	/** Interface for derived classes to populate this list. */
	public void populate(PoiRepository repo) {
		poiRepo_ = repo;
		channel_ = repo.channel_;
	}

	public final int size() {
		return poiSelected_ == null ? 0 : poiSelected_.size();
	}

	public final DisplayPoi getCurrentPOI() {
		if (poiSelected_.isEmpty()) {
			return null;
		}
		int sz = size();
		for (int i = 0; i < sz; i++) {
			DisplayPoi p = (DisplayPoi) poiSelected_.elementAt(i);
			if (p.getDisplayIndex() == currentIndex_) {
				return p;
			}
		}
		return null;
	}


	/** This have to be implemented by subclasses. */
	public Paging getPaging() {
		Channel ch = mid_.poiRepo_.channel_;
		return (ch == null) ? null : ch.paging_;
	}

	public void setCurrentView(BaseView bv) {
		bv_ = bv;
	}

	public POI[] getSelectedPOIs() {
		POI[] pois = null;
		if (poiSelected_ != null && poiSelected_.size() > 0) {
			pois = new POI[poiSelected_.size()];
			for (int i = 0; i < pois.length; i++) {
				pois[i] = ((DisplayPoi) poiSelected_.elementAt(i)).poi_;
			}
		}
		return pois;
	}

	public int getCurrentDisplayIndex() {
		return currentIndex_;
	}

	/**
	 * Return a POI's index within the array given a display index.
	 */
	public final int getPoiIndex(int displayIndex) {
		int idx = -1;
		int sz = poiSelected_ == null ? 0 : poiSelected_.size();
		for (int i = 0; i < sz; i++) {
			DisplayPoi p = (DisplayPoi) poiSelected_.elementAt(i);
			if (p.getDisplayIndex() == displayIndex) {
				idx = i;
				break;
			}
		}
		return idx;
	}

	public final DisplayPoi elementAt(int idx) {
		if (poiSelected_ == null || idx < 0)
			return null;
		else
			return poiSelected_.size() <= idx ? null : (DisplayPoi) poiSelected_.elementAt(idx);
	}

	/**
	 * Mark one POI as selected. This is used to set a displayed POI on the map as current POI.
	 * 
	 * @param idx
	 *            must be an index into _poiSelected vector. NOTE: Must allow index == array size because it's a display
	 *            index.
	 */
	public void setCurrentDisplayIndex(int idx) {
		if (idx >= 0 && idx <= poiSelected_.size()) {
			currentIndex_ = idx;
		}
	}

	public void removeAllElements() {
		poiSelected_.removeAllElements();
		currentIndex_ = -1;
	}


	public final boolean includeCurDispView() {
		return includeCurDispView_;
	}

	public final boolean isLast() {
		DisplayPoi dp = elementAt(size() - 1);
		return (dp != null && currentIndex_ == dp.getDisplayIndex());
	}

	public final boolean isFirst() {
		DisplayPoi dp = elementAt(0);
		return (dp != null && currentIndex_ == dp.getDisplayIndex());
	}

	/** Return true if the given POI is selected to be displayed on map. */
	public boolean isSelected(DisplayPoi poi) {
		return true;
	}
}
